﻿using Consul;
using HealthChecks.UI.Client;
using Micro.Core.Options;
using Micro.Core.Packages;
using Micro.Extensions.ServiceDiscovery;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Winton.Extensions.Configuration.Consul;

namespace Microsoft.Extensions.DependencyInjection
{
    /// <summary>
    /// 服务发现 consul
    /// </summary>
    public class ServiceDiscoveryPack : BasePackage
    {
      

        public override PackLevel Level => PackLevel.Framework;
        public override int Order => 1;

        public override IServiceCollection AddServices(IServiceCollection services)
        {
            services.AddHealthChecks();

            IConfiguration configuration = services.GetConfiguration();

            //Consul
            ServiceDiscoveryOption serviceDiscoveryOption = services.GetMicroOptions().ServiceDiscovery;
            if (serviceDiscoveryOption != null && serviceDiscoveryOption.Enabled  && serviceDiscoveryOption.ConsulUrl.NotNull())
            {
                services.AddSingleton<IConsulClient>(new ConsulClient(x =>
                {
                    x.Address = new Uri(serviceDiscoveryOption.ConsulUrl);
                }));
                services.AddHostedService<ConsulRegisterService>();
            }

            //Consul配置中心
            AddConsulConfig((configuration as ConfigurationManager)!);
            return services;
        }

        public override void UsePack(WebApplication app)
        {
            //base.UsePack(app);
            ServiceDiscoveryOption serviceDiscovery = app.Services.GetService<ServiceDiscoveryOption>()!;
            app.MapHealthChecks(serviceDiscovery.Health, new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
            {
                ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
            });
        }

        public override void UseHostBuilder(IHostBuilder hostBuilder, IServiceProvider services)
        {
            base.UseHostBuilder(hostBuilder, services);
        }


        /// <summary>
        /// Consul配置中心
        /// </summary>
        /// <param name="configurationManager"></param>
        private void AddConsulConfig(ConfigurationManager configurationManager)
        {
            var consulServerUrl = configurationManager["ConsulConfig:ConsulServerUrl"];
            var consulKey = configurationManager["ConsulConfig:ConsulKey"];
            if (consulServerUrl.NotNull() && consulKey.NotNull())
            {
                Console.WriteLine("启动Consul配置中心");
                //Consul配置中心
                configurationManager.AddConsul(consulKey, options =>
                {
                    options.Optional = true;
                    options.ReloadOnChange = true;
                    options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; };
                    options.ConsulConfigurationOptions = cco => { cco.Address = new Uri(consulServerUrl); };
                });
            }
        }
    }
}